package com.neusoft.ch5;
/*
 * 课堂笔记：
 * 1、方法（函数）
 *   方法：实现一个具体功能的代码的组合。方法就是一个语句块。
 *   语法：
 *       访问控制修饰符  其他修饰符  返回值类型  方法名(形参参数列表){
 *       	方法体(方法语句块);
 *       }
 *   解析：
 *      访问控制修饰符：控制方法的访问权限。常用 public protected  默认的(什么也不写) private
 *      其他修饰符：例如static final
 *      返回值类型：java的数据类型（8基本类型+引用类型）。
 *               如果不需要返回数据，则使用void进行修饰；
 *               除了void之后的其他的数据类型，都需要在方法体中使用  “return 返回值表达式；”的形式进行数据返回；
 *               ★如果是void的返回值类型，则在方法体中可以使用  “return；” 进行返回；（注意return后面没有表达式）
 *      方法名：按命名规范命名即可；
 *      形参参数列表：该方法可以传递的参数，如果有多个参数则使用逗号分隔；如果没有需要传递的参数则可以不用写形参参数列表；
 *                定义形式： 数据类型  变量名1,数据类型 变量名2,数据类型 变量名N
 *      {}：表示方法体的范围；
 *      方法体中：在方法体中会有返回值返回，则需要使用“return 返回值表达式；”的形式进行数据返回。
 *   注意：
 *      在声明定义方法时，应该要包括返回值类型、方法名、形参列表、方法体
 * 2、方法调用以及参数传值
 *    在一个方法中引用另外一个方法，叫做方法调用；
 *    方法调用的时候回产生传值；实参的值传递个形参；
 *    方法调用时给定的参数是实参，方法声明定义时给定的参数是形参；
 *    方法调用可以达到代码复用的目的；
 *    
 *    方法调用：    
 *       实参：方法调用时给定的参数；实参只是实参变量名即可；
 *       
 *       形参：方法声明定义时给定的参数；形参需要知名参数类型；
 *       形参和实参是针对于被调用的函数而言，是一种相对关系；
 *       
 *       在方法调用过程中，实参的值会传递给形参；
 *                    实参的个数、类型、顺序和形参要保持一致； 
 *       
 *       在子方法调用结束以后，形参的值是否会影响到实参？
 *       根据子方法执行完成之后，被改变的行参的值对实参有没有影响，可以将java的参数传递方式分为两种：
 *       必须记忆：
 *       一种：按值传参（本质是传递的值的拷贝）
 *               形参的值的变化不会影响实参的值；
 *               8种基本类型、String类型、8种基本类型的包装类类型
 *       一种：按引用传参（按地址传参） （本质传递的是地址）
 *               形参值的改变会影响实参的值；
 *               引用类型、数组都是按引用传参。（对象类型，除String外）
 *               
 *               
 *            按引用传参不能改变产生的地址引用，否则就沦为了按值传参。（当前不作要求）
 */
public class TestCh5 {

	public static void main(String[] args) {

		// 方法调用
		test02();
		System.out.println("==================================");
		test021();
	}

	/**
	 * 按值传参：形参值的改变不会影响实参的值
	 * 8种基本类型、String
	 */
	private static void test021() {
		// 变量
		int age0 = 20;
		System.out.println("调用子方法之前实参的值："+age0);
		// 调用子方法
		// age0是实参
		printInt(age0);
		//子方法调用完成以后再打印一下实参的值
		System.out.println("调用子方法之后实参的值："+age0);
	}
	
	/**
	 * 打印年龄
	 * @param age 形参年龄
	 */
	private static void printInt(int age) {
		//改变形参age
		age+=2;
		// 调用子函数
		// age是实参
		addInt(age);
		System.out.println("字方法中形参的值为："+age);
	}
	
	
	private static void addInt(int age) {
		//改变形参age
		age+=2;
		System.out.println("字方法中形参的值为："+age);
	}
	/**
	 * 按引用传参：形参的值的改变会影响实参的值。
	 * 引用类型变量、数组
	 */
	private static void test02() {
		// 定义一个数组
		int[] arr0 = new int[] {3,5,7,2,9,4,6};
		
		// 调用子方法之前打印数组内容
		System.out.println("调用子方法之前实参的值：");
		for (int i : arr0) {
			System.out.print("  "+i);
		}
		System.out.println();
		// 调用子方法打印数组内容
		// 在方法调用时给定的参数列表叫实参列表
		// arr0是实参
		// 子方法改变了形参的值
		printArr2(arr0); 
		
		// 调用子方法之后打印实参数组内容
		System.out.println("调用子方法之后实参的值：");
		for (int i : arr0) {
			System.out.print("  " + i);
		}
		System.out.println();
	}
	/**
	 * 打印数组（改变形参的值）
	 * @param arr 被打印的数组（形参）
	 */
	private static void printArr2(int[] arr) {
		
		// 改变形参数组的一个元素的值
		arr[0] = 0;
		/*int[] arrNew = new int[] {1,2,3};
		// 改变了形参的地址引用
		arr = arrNew;*/
		System.out.println("子方法中打印形参的内容：");
		// for循环打印数组
		for (int i = 0; i < arr.length; i++) {
			System.out.print("  "+arr[i]);			
		}
		// 换行
		System.out.println();
	}
	/**
	 * 
	 */
	private static void test01() {
		// 定义一个数组
		int[] arr0 = new int[] {3,5,7,2,9,4,6};
		// 调用子方法打印数组内容
		// 在方法调用时给定的参数列表叫实参列表
		// arr0是实参
		printArr(arr0); 
		
		
	}
	/**
	 * 打印数组
	 * @param arr 被打印的数组（形参）
	 */
	private static void printArr(int[] arr) {
		// for循环打印数组
		for (int i = 0; i < arr.length; i++) {
			System.out.print("  "+arr[i]);			
		}
		// 换行
		System.out.println();
	}
}
